﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web;
using System.Web.Configuration;
using System.Web.Http;
using System.Xml;
using AlipaySDK.Dto.Payment;
using AlipaySDK.Helper;
using Common.Logging;
using In.Api.Dto.HisWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Dto.Reg;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace User.Api.Controllers
{
    public class RegController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(RegController));
        //private GdsfybjyWeiXinEntities _ctx;

        private static readonly object OrderNoLocker = new object();
        private static readonly object PayNotifyLocker = new object();

        #region 获取挂号费用(没用)
        /// <summary>
        /// 获取挂号费用
        /// </summary>
        /// <param name="cardId">就诊卡id</param>
        /// <param name="deptId">科室</param>
        /// <param name="doctorId">医生</param>
        /// <param name="regDate">挂号日期</param>
        /// <param name="shiftCode">排班</param>
        /// <param name="svObjectId">服务对象</param>
        /// <returns></returns>
        //[HttpGet]
        //[ActionName("GetRegFee")]
        //public GetRegFeeResponse GetRegFee(int cardId, string deptId,string doctorId,string regDate,string shiftCode,string svObjectId)
        //{
        //    var azUser = AzUser.GetInApi(Request);
        //    string cardNo;
        //    using (var ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        var card = ctx.HospCards.Where(x => x.CardId == cardId && x.WxUserId == azUser.UserId)
        //            .Select(x => new
        //            {
        //                x.CardNo
        //            }).FirstOrDefault();
        //        if (card == null)
        //        {
        //            return new GetRegFeeResponse
        //            {
        //                ResultCode = "1",
        //                ResultMsg = "找不到就诊卡信息"
        //            };
        //        }
        //        cardNo = card.CardNo;
        //    }

        //    //执行服务对象操作
        //    var svRequest = new GetSvObjectRequest();
        //    svRequest.PatientId = cardNo;

        //    GetSvObjectResponse svResponse;
        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetSvObject", svRequest).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        svResponse = responseMsg.Content.ReadAsAsync<GetSvObjectResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内获取服务对象Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
        //        return new GetRegFeeResponse
        //        {
        //            ResultCode = "2",
        //            ResultMsg = "院内Api未返回"
        //        };
        //    }

        //    if (svResponse.ResultCode != "0")
        //    {
        //        return new GetRegFeeResponse
        //        {
        //            ResultCode = "3",
        //            ResultMsg = svResponse.ResultDesc
        //        };
        //    }

        //    //执行获取挂号费操作
        //    var request = new GetRegistFeeRequest();
        //    request.PatientId = cardNo;
        //    request.DeptId = deptId;
        //    request.DoctorId = doctorId;
        //    request.RegDate = regDate;
        //    request.SvObjectId = svResponse.SvObjects.FirstOrDefault()?.SvObjectId;
        //    request.ShiftCode = shiftCode;

        //    GetRegistFeeResponse response;
        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetRegistFee", request).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        response = responseMsg.Content.ReadAsAsync<GetRegistFeeResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内获取挂号费Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
        //        return new GetRegFeeResponse
        //        {
        //            ResultCode = "2",
        //            ResultMsg = "院内Api未返回"
        //        };
        //    }

        //    if (response.ResultCode != "0")
        //    {
        //        return new GetRegFeeResponse
        //        {
        //            ResultCode = "3",
        //            ResultMsg = response.ResultDesc
        //        };
        //    }

        //    return new GetRegFeeResponse
        //    {
        //        ResultCode = "0",
        //        ResultMsg = "",
        //        YhFee = response.YhFee.ToDecimalOrDefault()
        //    };
        //}
        #endregion

        /// <summary>
        /// 生成预约订单，包含锁号及预约操作
        /// </summary>
        /// <param name="cardId">就诊卡id</param>
        /// <param name="deptId">科室院内编号</param>
        /// <param name="deptName">科室名称</param>
        /// <param name="doctorId">医生院内编号</param>
        /// <param name="doctorName">医生名称</param>
        /// <param name="regDate">挂号日期</param>
        /// <param name="timeSlice">排班时段</param>
        /// <param name="startTime">分时开始时间</param>
        /// <param name="endTime">分时结束时间</param>
        /// <param name="regType">号源类型</param>
        /// <param name="sqno">分时序号</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("CreateApptOrder")]
        public CreateApptOrderResponse CreateApptOrder(int cardId, string deptId, string deptName,
            string doctorId, string doctorName, string regDate, string timeSlice, string startTime,
            string endTime, string regType, string sqno, string fee, string treatFee, string otherFee, string sourceCode)
        {
            //Logger.ErrorFormat("创建预约订单:{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}",
            //    cardId, deptId, deptName,  doctorId,  doctorName,  regDate,  timeSlice,  startTime,  endTime,  regType,  sqno,  fee,  treatFee,  otherFee,  sourceCode);
            var azUser = AzUser.GetInApi(Request);
            Card card;
            string openid;
            var today = DateTime.Now.ToString("yyyy-MM-dd");
            string regFlag;
            if (regDate == today)
            {
                regFlag = "2";//当天挂号
            }
            else
            {
                regFlag = "0";
            }

            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                card = _ctx.HospCards.Where(x => x.CardId == cardId && x.WxUserId == azUser.UserId)
                   .Select(x => new Card
                   {
                       CardNo = x.CardNo,
                       Birthdate = x.Birthdate,
                       CardType = x.CardType,
                       PatientName = x.PatientName
                   }).FirstOrDefault();
                if (card == null)
                {
                    return new CreateApptOrderResponse
                    {
                        ResultCode = "1",
                        ResultMsg = "找不到就诊卡信息"
                    };
                }

                var sameOrder = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
                    .Any(x =>
                        x.CardNo == card.CardNo
                        && x.RegDate == regDate
                        && x.DoctorId == doctorId
                        && x.TimeSlice == timeSlice);
                if (sameOrder)
                {
                    return new CreateApptOrderResponse
                    {
                        ResultCode = "2",
                        ResultMsg = "同个医生同个班次，只能挂号一次!"
                    };
                }

                if (deptName.Contains("内科") && (!deptName.Contains("儿")))
                {
                    DateTime birthday;
                    DateTime.TryParse(card.Birthdate, out birthday);
                    int age = DateTime.Now.Date.Year - birthday.Year;
                    if (birthday.AddYears(age).CompareTo(DateTime.Now.Date) == -1)
                    {
                        age = age - 1;
                    }
                    if (age < 18)
                    {
                        return new CreateApptOrderResponse
                        {
                            ResultCode = "3",
                            ResultMsg = "年龄未满18周岁，无法在内科门诊挂号!"
                        };
                    }
                }

                var cardSameDayAppointMax = ConfigurationManager.AppSettings["CardSameDayAppointMax"].ToInt32();
                var cardApptCount = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
                    .Count(x => x.CardNo == card.CardNo && x.RegDate == regDate);
                if (cardApptCount >= cardSameDayAppointMax)
                {
                    return new CreateApptOrderResponse
                    {
                        ResultCode = "4",
                        ResultMsg = "同一天最多可以预约挂号" + cardSameDayAppointMax + "次!"
                    };
                }
            }
            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var userobj = _ctx.WxUsers.FirstOrDefault(x => x.Id == azUser.UserId);
                openid = userobj == null ? "" : userobj.OpenId;
            }

            ApptOrder order;

            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                order = new ApptOrder
                {
                    WxUserId = azUser.UserId,
                    OrderType = regFlag,
                    HospitalId = "",
                    DeptId = deptId,
                    DeptName = deptName,
                    DoctorId = doctorId,
                    DoctorName = doctorName,
                    OrderNo = GenerateNewOrderNo(),
                    RegDate = regDate,
                    OrderStatus = ApptOrderExtensions.OrderStatus.未锁号.ToInt32(),
                    TimeSlice = timeSlice,
                    StartTime = startTime,
                    EndTime = endTime,
                    RegType = regType,
                    PayState = ApptOrderExtensions.PayState.未付款.ToInt32().ToString(),
                    Fee = fee.ToDecimalOrDefault(),
                    TreatFee = treatFee.ToDecimalOrDefault(),
                    OtherFee = otherFee.ToDecimalOrDefault(),
                    SumFee = fee.ToDecimalOrDefault() + treatFee.ToDecimalOrDefault() + otherFee.ToDecimalOrDefault(),
                    CreateTime = DateTime.Now,
                    Sqno = sourceCode,
                    RegNo = sqno,
                    CardNo = card.CardNo,
                    CardType = card.CardType.ToString(),
                    CardName = card.PatientName
                };

                _ctx.ApptOrders.Add(order);
                _ctx.SaveChanges();

                //order.OrderStatus = ApptOrderExtensions.OrderStatus.锁号中.ToInt32();
                //_ctx.SaveChanges();
                //_ctx.UpdateApptOrder(order.Id, ApptOrderExtensions.OrderStatus.锁号中.ToInt32());
            }
            DataBaseCommandFactory.CreateDatbaseCommand()
            .UpdateOrderStatus(order.Id, ApptOrderExtensions.OrderStatus.预约中.ToInt32());

            // 费用为0的直接设置为支付成功
            if (order.SumFee == 0)
            {
                //order.PayState = ApptOrderExtensions.PayState.已付款.ToInt32().ToString();
                //order.PayTime = DateTime.Now;
                //order.WxTransactionId = "0";
                //order.OrderStatus = ApptOrderExtensions.OrderStatus.支付成功.ToInt32();
                //_ctx.SaveChanges();
                DataBaseCommandFactory.CreateDatbaseCommand().PaySuccess(order.Id, "0");

                // RMQ 执行预约
                //var pickupingProducer = new OrderPickupingProducer();
                //pickupingProducer.Publish(new OrderPickupingMsg
                //{
                //    OrderType = OrderType.挂号订单,
                //    OrderId = order.Id
                //});

                return new CreateApptOrderResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    OrderId = order.Id,
                    OrderNo = order.OrderNo,
                    PayString = ""
                };
            }
            //order.OrderStatus = ApptOrderExtensions.OrderStatus.支付中.ToInt32();
            //_ctx.SaveChanges();
            DataBaseCommandFactory.CreateDatbaseCommand()
                .UpdateOrderStatus(order.Id, ApptOrderExtensions.OrderStatus.支付中.ToInt32());


            // RMQ 16分钟后如果还是支付中则设置支付失败
            var payingTimeoutProducer = new OrderPayingTimeoutProducer();
            payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
            {
                OrderType = OrderType.挂号订单,
                OrderId = order.Id
            }, 16 * 60 * 1000);

            //组织 微信 js 支付方法 getBrandWCPayRequest 的参数
            var payStartTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
            var payExpireTime = System.DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss");

            var payFee = order.SumFee.ToInt32().ToString();
           
            var superOpenIds = ConfigurationManager.AppSettings["OpenIdsForPayMin"]
                .Split(" , ", StringSplitOptions.RemoveEmptyEntries);
            if (superOpenIds.Contains(order.WxUserId.ToStringOrDefault()))
            {
                payFee = "0.01";
            }
          
            var result = WapPayment.ComposeWapPayParameter(new ComposeWapPayRequest
            {
                NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"] + "Reg/PaySucceed",
                CallBackUrl = MessageHelper.GetCallBackUrl("/index/do-reg-callback"),
                MerchantUrl = "",
                OutTradeNo = "AP" + order.OrderNo,
                Subject = "挂号缴费",
                TotalFee = payFee
            });

            var payRequestParam = result.RequestHtml;
          //  Logger.InfoFormat("组织支付宝js支付结束{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
            return new CreateApptOrderResponse
            {
                ResultCode = "0",
                ResultMsg = "",
                OrderId = order.Id,
                OrderNo = order.OrderNo,
                PayString = payRequestParam
            };
        }

        #region (不用)
        /// <summary>
        /// 生成直接挂号订单
        /// </summary>
        /// <returns></returns>
        /// <param name="cardId">就诊卡id</param>
        /// <param name="deptId">科室院内编号</param>
        /// <param name="deptName">科室名称</param>
        /// <param name="doctorId">医生院内编号</param>
        /// <param name="doctorName">医生名称</param>
        /// <param name="regDate">挂号日期</param>
        /// <param name="timeSlice">排班时段</param>
        /// <param name="startTime">分时开始时间</param>
        /// <param name="endTime">分时结束时间</param>
        /// <param name="regType">号源类型</param>
        /// <param name="fee">挂号费</param>
        /// <param name="treatFee">诊疗费</param>
        /// <param name="clinicUnitId">就诊单元</param>
        /// <param name="sqno">分时排班</param>
        /// <returns></returns>
        //[HttpGet]
        //[ActionName("CreateDirectOrder")]
        //public CreateDirectOrderResponse CreateDirectOrder(int cardId, string deptId, string deptName,
        //    string doctorId, string doctorName, string regDate, string timeSlice, string startTime,
        //    string endTime, string regType, decimal? fee, decimal? treatFee,string clinicUnitId, string sqno)
        //{
        //    var azUser = AzUser.GetInApi(Request);
        //    Card card;
        //    using (var _ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        card = _ctx.HospCards.Where(x => x.CardId == cardId && x.WxUserId == azUser.UserId)
        //           .Select(x => new Card
        //           {
        //               CardNo = x.CardNo,
        //               Birthdate = x.Birthdate,
        //               CardType = x.CardType,
        //               PatientName = x.PatientName
        //           }).FirstOrDefault();
        //        if (card == null)
        //        {
        //            return new CreateDirectOrderResponse
        //            {
        //                ResultCode = "1",
        //                ResultMsg = "找不到就诊卡信息"
        //            };
        //        }


        //        var sameOrder = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
        //            .Any(x =>
        //                x.CardNo == card.CardNo
        //                && x.RegDate == regDate
        //                && x.DoctorId == doctorId
        //                && x.TimeSlice == timeSlice);
        //        if (sameOrder)
        //        {
        //            return new CreateDirectOrderResponse
        //            {
        //                ResultCode = "2",
        //                ResultMsg = "同个医生同个班次，只能挂号一次!"
        //            };
        //        }

        //        if (deptName.Contains("内科") && (!deptName.Contains("儿")))
        //        {
        //            DateTime birthday;
        //            DateTime.TryParse(card.Birthdate, out birthday);
        //            int age = DateTime.Now.Date.Year - birthday.Year;
        //            if (birthday.AddYears(age).CompareTo(DateTime.Now.Date) == -1)
        //            {
        //                age = age - 1;
        //            }
        //            if (age < 18)
        //            {
        //                return new CreateDirectOrderResponse
        //                {
        //                    ResultCode = "3",
        //                    ResultMsg = "年龄未满18周岁，无法在内科门诊挂号!"
        //                };
        //            }
        //        }

        //        var cardSameDayAppointMax = ConfigurationManager.AppSettings["CardSameDayAppointMax"].ToInt32();
        //        var cardApptCount = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
        //            .Count(x => x.CardNo == card.CardNo && x.RegDate == regDate);
        //        if (cardApptCount >= cardSameDayAppointMax)
        //        {
        //            return new CreateDirectOrderResponse
        //            {
        //                ResultCode = "4",
        //                ResultMsg = "同一天最多可以预约挂号" + cardSameDayAppointMax + "次!"
        //            };
        //        }
        //    }
        //    //执行服务对象操作
        //    Logger.InfoFormat("执行服务对象操作开始{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    var svRequest = new GetSvObjectRequest();
        //    svRequest.PatientId = card.CardNo;

        //    GetSvObjectResponse svResponse;
        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetSvObject", svRequest).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        svResponse = responseMsg.Content.ReadAsAsync<GetSvObjectResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内获取服务对象Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "5",
        //            ResultMsg = "获取挂号费用信息超时"
        //        };
        //    }
        //    Logger.InfoFormat("执行服务对象操作结束{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    if (svResponse.ResultCode != "0")
        //    {
        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "6",
        //            ResultMsg = svResponse.ResultDesc
        //        };
        //    }

        //    //执行获取挂号费操作
        //    Logger.InfoFormat("执行获取挂号费操作开始{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    var feeRequest = new GetRegistFeeRequest();
        //    feeRequest.PatientId = card.CardNo;
        //    feeRequest.DeptId = deptId;
        //    feeRequest.DoctorId = doctorId;
        //    feeRequest.RegDate = regDate;
        //    feeRequest.SvObjectId = svResponse.SvObjects.FirstOrDefault()?.SvObjectId;
        //    feeRequest.ShiftCode = timeSlice;

        //    GetRegistFeeResponse feeResponse;
        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetRegistFee", feeRequest).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        feeResponse = responseMsg.Content.ReadAsAsync<GetRegistFeeResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内获取挂号费Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "5",
        //            ResultMsg = "获取挂号费用信息超时"
        //        };
        //    }
        //    Logger.InfoFormat("执行获取挂号费操作结束{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    if (feeResponse.ResultCode != "0")
        //    {
        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "6",
        //            ResultMsg = feeResponse.ResultDesc
        //        };
        //    }


        //    var otherFee = 0;
        //    ApptOrder order;
        //    using (var _ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        order = new ApptOrder
        //        {
        //            WxUserId = azUser.UserId,
        //            OrderType = ApptOrderExtensions.OrderType.直接挂号.ToInt32().ToString(),
        //            HospitalId = "1036",
        //            DeptId = deptId,
        //            DeptName = deptName,
        //            DoctorId = doctorId,
        //            DoctorName = doctorName,
        //            OrderNo = GenerateNewOrderNo(),
        //            RegDate = regDate,
        //            OrderStatus = ApptOrderExtensions.OrderStatus.未锁号.ToInt32(),
        //            TimeSlice = timeSlice,
        //            StartTime = startTime,
        //            EndTime = endTime,
        //            RegType = regType,
        //            PayState = ApptOrderExtensions.PayState.未付款.ToInt32().ToString(),
        //            Fee = fee,
        //            TreatFee = treatFee,
        //            OtherFee = otherFee,
        //            SumFee = fee + treatFee + otherFee - (feeResponse.YhFee.ToDecimalOrDefault() / 100.0m),
        //            CreateTime = DateTime.Now,
        //            CardNo = card.CardNo,
        //            CardType = card.CardType.ToString(),
        //            CardName = card.PatientName,
        //            SvObjectId = svResponse.SvObjects.FirstOrDefault()?.SvObjectId
        //        };

        //        _ctx.ApptOrders.Add(order);
        //        _ctx.SaveChanges();
        //    }


        //    // 执行当天挂号锁号操作
        //    Logger.InfoFormat("执行当天挂号锁号操作开始{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    var apptRequest = new ExeLockSourceRequest();
        //    apptRequest.LockId = order.OrderNo;
        //    apptRequest.DeptId = deptId;
        //    apptRequest.ClinicUnitId = clinicUnitId;
        //    apptRequest.PatientId = card.CardNo;
        //    apptRequest.PatientName = card.PatientName;
        //    apptRequest.DoctorId = doctorId;
        //    apptRequest.RegDate = regDate;
        //    apptRequest.ShiftCode = timeSlice;
        //    apptRequest.StartTime = startTime;
        //    apptRequest.EndTime = endTime;
        //    apptRequest.PeriodId = sqno;
        //    apptRequest.SvObjectId = svResponse.SvObjects.FirstOrDefault()?.SvObjectId;
        //    apptRequest.RegFee = (fee*100).ToString();
        //    apptRequest.TreatFee = (treatFee*100).ToString();
        //    apptRequest.Remark = "";

        //    ExeLockSourceResponse apptResponse;
        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/ExeLockSource", apptRequest).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        apptResponse = responseMsg.Content.ReadAsAsync<ExeLockSourceResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内预约Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

        //        DataBaseCommandFactory.CreateDatbaseCommand()
        //        .UpdateOrderStatus(order.Id, ApptOrderExtensions.OrderStatus.锁号失败.ToInt32());

        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "7",
        //            ResultMsg = "执行锁号操作超时"
        //        };
        //    }
        //    Logger.InfoFormat("执行当天挂号锁号操作结束{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    if (apptResponse.ResultCode != "0")
        //    {
        //        DataBaseCommandFactory.CreateDatbaseCommand()
        //        .UpdateOrderStatus(order.Id, ApptOrderExtensions.OrderStatus.锁号失败.ToInt32());

        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "8",
        //            ResultMsg = apptResponse.ResultDesc
        //        };
        //    }

        //    DataBaseCommandFactory.CreateDatbaseCommand().LockSuccessAndAppt(order.Id, apptResponse.InfoSeq);

        //    // 费用为0的直接设置为支付成功
        //    if (order.SumFee == 0)
        //    {
        //        DataBaseCommandFactory.CreateDatbaseCommand().PaySuccess(order.Id, "0");

        //        // RMQ 执行取号
        //        var pickupingProducer = new OrderPickupingProducer();
        //        pickupingProducer.Publish(new OrderPickupingMsg
        //        {
        //            OrderType = OrderType.挂号订单,
        //            OrderId = order.Id
        //        });

        //        return new CreateDirectOrderResponse
        //        {
        //            ResultCode = "0",
        //            ResultMsg = "",
        //            OrderId = order.Id,
        //            OrderNo = order.OrderNo,
        //            PayString = ""
        //        };
        //    }

        //    DataBaseCommandFactory.CreateDatbaseCommand().UpdateOrderStatus(order.Id, ApptOrderExtensions.OrderStatus.支付中.ToInt32());
        //    Logger.InfoFormat("获取支付宝支付开始{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    // RMQ 16分钟后如果还是支付中则设置支付失败
        //    var payingTimeoutProducer = new OrderPayingTimeoutProducer();
        //    payingTimeoutProducer.Publish(new OrderPayingTimeoutMsg
        //    {
        //        OrderType = OrderType.挂号订单,
        //        OrderId = order.Id
        //    }, 16 * 60 * 1000);

        //    //组织 微信 js 支付方法 getBrandWCPayRequest 的参数
        //    var payFee = order.SumFee.ToString();
        //    var superOpenIds = ConfigurationManager.AppSettings["OpenIdsForPayMin"]
        //        .Split(" , ", StringSplitOptions.RemoveEmptyEntries);
        //    if (superOpenIds.Contains(order.WxUserId.ToStringOrDefault()))
        //    {
        //        payFee = "0.01";
        //    }

        //    //var payRequestParam = TenpayV2Helper.GenerateWxPayParameter("就诊挂号", "AP" + order.OrderNo,
        //    //    payFee, GetClientIp(), payStartTime, payExpireTime, "Reg/PaySucceed");
        //    var result = WapPayment.ComposeWapPayParameter(new ComposeWapPayRequest
        //    {
        //        NotifyUrl = WebConfigurationManager.AppSettings["AlipayNotify"] + "Reg/PaySucceed",
        //        CallBackUrl = MessageHelper.GetCallBackUrl("/index/do-reg-callback"),
        //        MerchantUrl = "",
        //        OutTradeNo = "AP" + order.OrderNo,
        //        Subject = "挂号缴费",
        //        TotalFee = payFee
        //    });

        //    var payRequestParam = result.RequestHtml;
        //    Logger.InfoFormat("获取支付宝支付结束{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
        //    return new CreateDirectOrderResponse
        //    {
        //        ResultCode = "0",
        //        ResultMsg = "",
        //        OrderId = order.Id,
        //        OrderNo = order.OrderNo,
        //        PayString = payRequestParam
        //    };
        //}

        /// <summary>
        /// 非微信平台预约记录查询
        /// </summary>
        /// <param name="cardId"></param>
        /// <returns></returns>
        //[HttpGet]
        //[ActionName("GetOtherApptOrderList")]
        //public GetOtherApptOrderListResponse GetOtherApptOrderList(int cardId)
        //{
        //    var azUser = AzUser.GetInApi(Request);
        //    string cardNo;

        //    using (var _ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        var card = _ctx.HospCards.Where(x => x.CardId == cardId && x.WxUserId == azUser.UserId)
        //            .Select(x => new
        //            {
        //                x.CardNo
        //            }).FirstOrDefault();
        //        if (card == null)
        //        {
        //            return new GetOtherApptOrderListResponse
        //            {
        //                ResultCode = "1",
        //                ResultMsg = "找不到就诊卡信息"
        //            };
        //        }
        //        cardNo = card.CardNo;
        //    }


        //    var resSourceRequest = new GetResSourceRequest();
        //    resSourceRequest.CardNo = cardNo;

        //    GetResSourceResponse resSourceResponse;

        //    try
        //    {
        //        var httpClient = InHttpClient.GetClient();
        //        var responseMsg = httpClient.PostAsJsonAsync("HisSp/GetResSource", resSourceRequest).Result;
        //        responseMsg.EnsureSuccessStatusCode();
        //        resSourceResponse = responseMsg.Content.ReadAsAsync<GetResSourceResponse>().Result;
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.ErrorFormat("调用院内获取取号查询（非微信平台）Api出错,信息：{0}", JsonConvert.SerializeObject(ex));
        //        return new GetOtherApptOrderListResponse
        //        {
        //            ResultCode = "2",
        //            ResultMsg = "获取取号查询信息超时"
        //        };
        //    }

        //    if (resSourceResponse.ResultCode != "0")
        //    {
        //        return new GetOtherApptOrderListResponse
        //        {
        //            ResultCode = "3",
        //            ResultMsg = resSourceResponse.ResultDesc
        //        };
        //    }
        //    using (var _ctx = new GdsfybjyWeiXinEntities())
        //    {
        //        var otherApptOrderList =
        //            resSourceResponse.ScheduleList.Select(x =>
        //            {
        //                var doctorTitle = "";
        //                var doctor = _ctx.Doctors.FirstOrDefault(y => y.DeptId == x.DeptId && y.DoctorId == x.DoctorId);
        //                if (doctor != null)
        //                {
        //                    doctorTitle = doctor.Title ?? "";
        //                }
        //                return new GetOtherApptOrderListResponse.OtherApptOrder()
        //                {
        //                    DeptId = x.DeptId,
        //                    DeptName = x.DeptName,
        //                    DoctorId = x.DoctorId,
        //                    DoctorName = x.DoctorName,
        //                    DoctorTitle = doctorTitle,
        //                    RegType = x.RegType,
        //                    RegDate = x.RegDate,
        //                    TimeSlice = x.TimeSlice,
        //                    StartTime = x.StartTime,
        //                    EndTime = x.EndTime,
        //                    Fee = x.Fee.ToDecimalOrDefault(),
        //                    TreatFee = x.TreatFee.ToDecimalOrDefault(),
        //                    OtherFee = x.OtherFee.ToDecimalOrDefault(),
        //                    SumFee = (x.Fee.ToDecimalOrDefault() + x.TreatFee.ToDecimalOrDefault()
        //                              + x.OtherFee.ToDecimalOrDefault()),
        //                    RegNo = x.RegNo
        //                };
        //            }).ToList();
        //        return new GetOtherApptOrderListResponse()
        //        {
        //            ResultCode = "0",
        //            ResultMsg = "",
        //            OtherApptOrders = otherApptOrderList
        //        };
        //    }
        //}
        #endregion

        /// <summary>
        /// 手工退费
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ActionName("test")]
        [AllowAnonymous]
        public WapPayRefundResponse test()
        {
            WapPayRefundResponse refundResult = WapPayment.WapPayRefund(new WapPayRefundRequest
            {

                NotifyUrl = ConfigurationManager.AppSettings["AlipayNotify"] + "Reg/PaySucceed",
                BatchNo = DateTime.Now.ToString("yyyyMMddhhmmss") + DateTime.Now.Millisecond,
                RefundDate = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                BatchNum = "1",
                DetailData = "2017022821001004940249882932" + "^" + "1.5" + "^因退号而退款"
            });
            //var a = WeixinPayV3Helper.DoRefund("APWX2017021430285379", "4001772001201702149859132258", "APWX2017021430285379", 400, 400);
            return new WapPayRefundResponse
            {
                ResultCode = "0",
                ResultMsg = "",

            };
        }

        /// <summary>
        /// 用户取消支付
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("PayFailed")]
        public PayFailedResponse PayFailed(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);

            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var order = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.支付中)
                    .Where(x => x.WxUserId == azUser.UserId && x.Id == orderId).Select(x => new
                    {
                        x.OrderType
                    }).FirstOrDefault();
                if (order == null)
                {
                    return new PayFailedResponse
                    {
                        ResultCode = "1",
                        ResultMsg = "订单不存在"
                    };
                }

                DataBaseCommandFactory.CreateDatbaseCommand()
                    .UpdateOrderStatus(orderId, ApptOrderExtensions.OrderStatus.支付失败.ToInt32());
            }

            // RMQ 执行取消预约或锁号操作
            var unapptingProducer = new OrderUnapptingProducer();
            unapptingProducer.Publish(new OrderUnapptingMsg
            {
                OrderType = Rmq.Center.OrderType.挂号订单,
                OrderId = orderId
            });


            return new PayFailedResponse
            {
                ResultCode = "0",
                ResultMsg = ""
            };
        }

        /// <summary>
        /// 微信支付通知回调
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        [ActionName("PaySucceed")]
        public HttpResponseMessage PaySucceed()
        {

            Dictionary<string, string> sPara = AlipayNotifyHelper.GetRequestPost();
            string sign = HttpContext.Current.Request.Form["sign"];
            var result =
                WapPayment.WapPayVerifyNotify(new WapPayVerifyNotifyRequest
                {
                    SPara = sPara,
                    Sign = sign
                });

            if (result != null && result.ResultCode == "0")
            {
                //Logger.Info(result.NotifyData);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(result.NotifyData);
                string transactionId = xmlDoc.SelectSingleNode("/notify/trade_no")?.InnerText ?? "";
                string trade_status = xmlDoc.SelectSingleNode("/notify/trade_status")?.InnerText ?? "";
                string notify_id = xmlDoc.SelectSingleNode("/notify/notify_id")?.InnerText ?? "";
                var outTradeNo = xmlDoc.SelectSingleNode("/notify/out_trade_no")?.InnerText ?? "";
                decimal total_fee = (xmlDoc.SelectSingleNode("/notify/total_fee")?.InnerText).ToDecimalOrDefault();
                string buyer_id = xmlDoc.SelectSingleNode("/notify/buyer_id")?.InnerText ?? "";
                string timeEnd = xmlDoc.SelectSingleNode("/notify/gmt_payment")?.InnerText;
                string seller_email = xmlDoc.SelectSingleNode("/notify/seller_email")?.InnerText;


                lock (PayNotifyLocker)
                {
                    try
                    {
                        OrderBase order = null;
                        using (var _ctx = new GdsfybjyWeiXinEntities())
                        {
                            if (_ctx.WxPayNotifyLogs.Any(
                                x => x.TransactionId == transactionId && x.TradeState == 1))
                            {
                                return new HttpResponseMessage
                                {
                                    StatusCode = HttpStatusCode.OK,
                                    Content = new StringContent("success")
                                };
                            }
                            if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                            {
                                if (outTradeNo.StartsWith("AP"))
                                {
                                    var orderNo = outTradeNo.Substring(2);
                                     order = _ctx.ApptOrders.Where(x => x.OrderNo == orderNo).Select(x => new OrderBase
                                     {
                                         OrderStatus = x.OrderStatus,
                                         Id = x.Id,
                                         SumFee = x.SumFee
                                     }).FirstOrDefault();
                                }
                            }
                        }
                        if (order != null)
                        {
                            if (order.OrderStatus == ApptOrderExtensions.OrderStatus.支付中.ToInt32())
                            {
                                DataBaseCommandFactory.CreateDatbaseCommand()
                                    .WeixinPaySuccess(order.Id, transactionId, timeEnd);

                                // RMQ 执行取号操作
                                var pickupingProducer = new OrderPickupingProducer();
                                pickupingProducer.Publish(new OrderPickupingMsg
                                {
                                    OrderType = Rmq.Center.OrderType.挂号订单,
                                    OrderId = order.Id
                                });
                            }
                            else if (order.OrderStatus ==
                                     ApptOrderExtensions.OrderStatus.取消预约成功.ToInt32() ||
                                     order.OrderStatus == ApptOrderExtensions.OrderStatus.支付失败.ToInt32())
                            {
                                //如果订单状态为取消预约成功、支付失败
                                // RMQ 执行退费操作
                                if (order.SumFee > 0)
                                {
                                    var refundingProducer = new OrderRefundingPickupFailedProducer();
                                    refundingProducer.Publish(new OrderRefundingPickupFailedMsg
                                    {
                                        OrderType = OrderType.挂号订单,
                                        OrderId = order.Id
                                    });
                                }
                            }

                        }

                        #region 记录通过验证的支付通知

                        using (var _ctx = new GdsfybjyWeiXinEntities())
                        {
                            //记录通知日志
                            var orderNotifyLog = new WxPayNotifyLog
                            {
                                ServiceVersion = "2.0",
                                Attach = "",
                                BankBillNo = "",
                                BankType = "AliPay",
                                BuyerAlias = "",
                                Discount = 0,
                                FeeType = 1,
                                InputCharset = "utf-8",
                                NotifyId = notify_id,
                                SignType = "0001",
                                Sign = "", //Request.Form["sign"],
                                SignKeyIndex = 0,
                                TradeMode = 1,
                                PayInfo = "",
                                //Partner = xmlDoc.SelectSingleNode("/notify/seller_id").InnerText,
                                TotalFee = (total_fee*100).ToInt32OrDefault(),
                                TransactionId = transactionId,
                                OutTradeNo = outTradeNo,
                                //TimerEnd = xmlDoc.SelectSingleNode("/notify/gmt_payment").InnerText,
                                TransportFee = 0,
                                ProductFee = (total_fee*100).ToInt32OrDefault(),
                                PostAppId = seller_email,
                                PostTimeStamp = timeEnd,
                                PostNonceStr = "",
                                PostOpenId = buyer_id,
                                PostAppSignature = trade_status,
                                PostIsSubscribe = "1",
                                RecCreateDt = DateTime.Now
                            };
                            if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                                orderNotifyLog.TradeState = 1;
                            _ctx.WxPayNotifyLogs.Add(orderNotifyLog);
                            _ctx.SaveChanges();
                        }

                        #endregion

                        return new HttpResponseMessage
                        {
                            StatusCode = HttpStatusCode.OK,
                            Content = new StringContent("success")
                        };
                    }
                    catch (System.Data.SqlClient.SqlException sqlEx)
                    {
                        Logger.ErrorFormat("Reg PaySuccessed SqlException Error:{0}",
                            JsonConvert.SerializeObject(sqlEx));
                    }
                    catch (Exception e)
                    {
                        Logger.ErrorFormat("Reg PaySuccessed Error:{0}", JsonConvert.SerializeObject(e));

                    }
                }

            }

            #region 记录验证失败的支付通知

            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var unverifiedNotifyLog = new WxPayNotifyLog();
                //unverifiedNotifyLog.PayInfo = Request.RequestUri.AbsoluteUri;
                unverifiedNotifyLog.TradeState = 0;
                unverifiedNotifyLog.RecCreateDt = DateTime.Now;
                _ctx.WxPayNotifyLogs.Add(unverifiedNotifyLog);
                _ctx.SaveChanges();
            }

            #endregion

            return new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("fail")
            };
        }

        /// <summary>
        /// 获取挂号状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetRegStatus")]
        public GetRegStatusResponse GetRegStatus(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var order = _ctx.ApptOrders.Where(x => x.Id == orderId && x.WxUserId == azUser.UserId)
                    .Select(x => new
                    {
                        x.OrderStatus
                    }).FirstOrDefault();
                if (order == null)
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "1",
                        ResultMsg = "订单不存在"
                    };
                }

                if (order.OrderStatus == ApptOrderExtensions.OrderStatus.取号中.ToInt32()
                    || order.OrderStatus == ApptOrderExtensions.OrderStatus.支付中.ToInt32()
                    || order.OrderStatus == ApptOrderExtensions.OrderStatus.支付成功.ToInt32())
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "0",
                        ResultMsg = "",
                        RegStatus = "2",
                        FailedMsg = ""
                    };
                }

                if (order.OrderStatus == ApptOrderExtensions.OrderStatus.取号成功.ToInt32())
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "0",
                        ResultMsg = "",
                        RegStatus = "0",
                        FailedMsg = ""
                    };
                }

                return new GetRegStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    RegStatus = "1",
                    FailedMsg = ""
                };
            }
        }

        /// <summary>
        /// 退号操作
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("Unpickup")]
        public UnpickupResponse Unpickup(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var order = _ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
                    .Where(x => x.WxUserId == azUser.UserId
                                && x.Id == orderId).Select(x => new
                                {
                                    x.RegDate,
                                    x.OrderType
                                }).FirstOrDefault();
                if (order == null || order.OrderType != ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
                {
                    return new UnpickupResponse
                    {
                        ResultCode = "1",
                        ResultMsg = "找不到订单"
                    };
                }

                if (string.CompareOrdinal(order.RegDate ?? "", DateTime.Today.ToString("yyyy-MM-dd")) <= 0)
                {
                    return new UnpickupResponse
                    {
                        ResultCode = "2",
                        ResultMsg = "退预约号必须至少提前1天"
                    };
                }

            }

            // RMQ 执行退号
            var unpickupProducer = new OrderUnpickupingProducer();
            unpickupProducer.Publish(new OrderUnpickupingMsg
            {
                OrderType = OrderType.挂号订单,
                OrderId = orderId
            });

            return new UnpickupResponse
            {
                ResultCode = "0",
                ResultMsg = ""
            };
        }

        /// <summary>
        /// 获取取消挂号状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpGet]
        [ActionName("GetCancellRegStatus")]
        public GetRegStatusResponse GetCancellRegStatus(int orderId)
        {
            var azUser = AzUser.GetInApi(Request);
            using (var _ctx = new GdsfybjyWeiXinEntities())
            {
                var order = _ctx.ApptOrders.Where(x => x.Id == orderId && x.WxUserId == azUser.UserId)
                    .Select(x => new
                    {
                        x.OrderStatus,
                        x.SumFee
                    }).FirstOrDefault();
                if (order == null)
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "1",
                        ResultMsg = "订单不存在"
                    };
                }

                //对于订单金额为0的挂号单，微信退号中就算成功
                if (order.SumFee == 0 && order.OrderStatus == ApptOrderExtensions.OrderStatus.微信退号中.ToInt32())
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "0",
                        ResultMsg = "",
                        RegStatus = "0",
                        FailedMsg = ""
                    };
                }

                if (order.OrderStatus == ApptOrderExtensions.OrderStatus.微信退号中.ToInt32()
                    || order.OrderStatus == ApptOrderExtensions.OrderStatus.微信退号成功.ToInt32()
                    || order.OrderStatus == ApptOrderExtensions.OrderStatus.微信退号退款中.ToInt32())
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "0",
                        ResultMsg = "",
                        RegStatus = "2",
                        FailedMsg = ""
                    };
                }

                if (order.OrderStatus == ApptOrderExtensions.OrderStatus.微信退号退款成功.ToInt32())
                {
                    return new GetRegStatusResponse
                    {
                        ResultCode = "0",
                        ResultMsg = "",
                        RegStatus = "0",
                        FailedMsg = ""
                    };
                }

                return new GetRegStatusResponse
                {
                    ResultCode = "0",
                    ResultMsg = "",
                    RegStatus = "1",
                    FailedMsg = ""
                };
            }
        }

        /// <summary>
        /// 生成挂号订单号
        /// </summary>
        /// <returns></returns>
        public string GenerateNewOrderNo()
        {
            var orderNo = "AL" + DateTime.Now.Date.ToString("yyyyMMdd");
            lock (OrderNoLocker)
            {
                orderNo += (DateTime.Now - DateTime.Now.Date).TotalMilliseconds.ToString("00000000");
                Thread.Sleep(1);
            }

            return orderNo;
        }

        public string GetClientIp()
        {
            if (Request.Properties.ContainsKey("MS_HttpContext"))
            {
                string ip = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                //判断是否有代理服务器
                if (string.IsNullOrEmpty(ip))
                {
                    //没有代理服务器,如果有代理服务器获取的是代理服务器的IP
                    ip = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                }

                string pattrn = @"(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])";
                if (!string.IsNullOrEmpty(ip) && System.Text.RegularExpressions.Regex.IsMatch(ip, pattrn))
                {
                    return ip;
                }

                return "127.0.0.1";
            }
            else
            {
                return "127.0.0.1";
            }
        }
    }
}
